---
title: Webhooks FAQ
subtitle: How Skyvern notifies you when its done
slug: running-tasks/webhooks-faq
---
## Webhooks vs HTTP requests?

Task runtimes can exceed default HTTP timeouts; we recommend using webhook notifications to inform you when the run is complete.

To set up webhook callback:
- Set [webhook_url in Run Task](/api-reference/api-reference/agent/run-task#request.body.webhook_url) to receive the update when the task is done.
- Set [webhook_url in Run Workflow](/api-reference/api-reference/workflows/run-workflow#request.body.webhook_url) to receive the update when a workflow run is done.

To fetch the status of a run:
- Use the [Get Run](/api-reference/api-reference/agent/get-run) endpoint for the status of a task or workflow run 

## Webhook payload schema

The webhook request body is a JSON object with the following fields:
```json
{
   "run_id": "The ID of the task or the workflow run. For examples: tsk_123, tsk_v2_123, wr_123",
   "run_type": "The type of the run. Examples: task_v1, task_v2, workflow_run, openai_cua, anthropic_cua.",
   "status": "The status of the run",
   "output": "The output of the run",
   "downloaded_files": "A list of download file objects",
   "recording_url": "The URL of the recording",
   "screenshot_urls": "URLs of the last three screenshots. The first one in the list is the latest screenshot.",
   "failure_reason": "The reason for the failure if any",
   "app_url": "The URL to the run in the Skyvern app",
   "browser_session_id": "The ID of the browser session",
   "max_screenshot_scrolls": "The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot",
   "run_request": "The original request parameters used to start this task or workflow run",
   "script_run": "The script run result containing information like whether AI fallback is triggered when the script fails",
   "created_at": "The timestamp when the run was created",
   "modified_at": "The timestamp when the run was last modified",
   "queued_at": "The timestamp when the run was queued",
   "started_at": "The timestamp when the run started",
   "finished_at": "The timestamp when the run finished"
}
```
For detailed schema, please refer to the [Run Response](/api-reference/api-reference/agent/get-run#response).

Notes:
- The webhook payload won't contain the `run_request` field as the [Run Response](/api-reference/api-reference/agent/get-run#response) does.
- There are legacy fields in the actual payload for backward compatibility, which are not listed here and will be removed in the future. Please use the fields above. 

## How do we handle webhook authentication? (ie how can we handle callbacks?)

<CodeGroup>
```python Python
import hmac
from fastapi import Request

def validate_skyvern_request_headers(request: Request) -> bool:
    header_skyvern_signature = request.headers["x-skyvern-signature"]
    payload = request.body() # this is a bytes
    hash_obj = hmac.new(SKYVERN_API_KEY.encode("utf-8"), msg=payload, digestmod=hashlib.sha256)
    client_generated_signature = hash_obj.hexdigest()
    return header_skyvern_signature == client_generated_signature
```

```javascript Javascript
const crypto = require('crypto');

function validateSkyvernRequestHeaders(req) {
    const headerSkyvernSignature = req.headers['x-skyvern-signature'];
    const payload = req.body; // assuming req.body is a Buffer or string
    const hash = crypto.createHmac('sha256', process.env.SKYVERN_API_KEY)
                        .update(payload)
                        .digest('hex');
    return headerSkyvernSignature === hash;
}
```

</CodeGroup>

## Can I Replay Webhook?

Yes, you can replay a webhook by using the [Retry Webhook](/api-reference/api-reference/agent/retry-run-webhook) endpoint.